import datetime
import os
import uuid
from django.contrib.auth.hashers import make_password, check_password
from django.conf import settings
from django.utils import timezone
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.decorators import api_view, permission_classes
from rest_framework_simplejwt.tokens import RefreshToken
from user.models import SysUser
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.pagination import PageNumberPagination
from role.models import Role, UserRole


# Create your views here.
# 注册用户信息视图类
class RegisterView(APIView):
    permission_classes = [AllowAny]  # 允许任何⽤户访问

    def post(self, request):
        """
        用户注册
        :param request:
        :return:
        """
        username = request.data.get('username')  # 获取用户名
        password = request.data.get('password')  # 获取密码
        email = request.data.get('email', '')  # 获取邮箱
        phonenumber = request.data.get('phonenumber', '')  # 获取手机号
        print(username, password, email, phonenumber)

        if not username or not password:
            return Response({
                'code': 400,
                'message': '⽤户名和密码不能为空'
            }, status=status.HTTP_400_BAD_REQUEST)
        # 检查⽤户名是否已存在
        if SysUser.objects.filter(username=username).exists():
            return Response({
                'code': 400,
                'message': '⽤户名已存在'
            })

        # 写入数据到MySQL库
        try:
            user = SysUser.objects.create(
                username=username,  # 用户名
                password=make_password(password),  # 密码
                email=email,  # 邮箱
                phonenumber=phonenumber,  # 手机号
                nickname=username,  # 默认昵称与用户名一致
                gender='other',  # 默认性别为 other
                status=0,  # 默认正常状态
                create_time=datetime.datetime.now(),  # 创建时间
                update_time=datetime.datetime.now()  # 更新时间
            )

        except Exception as e:
            return Response({
                'code': 500,
                'message': f'注册失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response({
            'code': 200,
            'message': '注册成功',
            'data': {
                'id': user.id,
                'username': user.username,
                'email': user.email
            }
        })


class LoginView(APIView):
    permission_classes = [AllowAny]  # 允许任何⽤户访问

    def post(self, request):
        """
        用户注册
        :param request:
        :return:
        """
        # 1.获取登录用户和密码信息
        username = request.data.get('username')  # 获取用户名
        password = request.data.get('password')  # 获取密码
        print(username, password)
        # 2.判断登录信息是否完整
        if not username or not password:
            return Response({
                'code': 400,
                'message': '⽤户名和密码不能为空'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 3.通过用户名获取用户对象
            user = SysUser.objects.get(username=username)  # 根据⽤户名获取⽤户对象
            # 4.验证密码的是否正确
            if check_password(password, user.password):
                # 生成 token
                # 5.⽣成JWT令牌刷新令牌
                # RefreshToken.for_user(用户表信息)-- 刷新令牌
                refresh = RefreshToken.for_user(user)
                # 获取访问令牌
                access_token = str(refresh.access_token)
                print("access_token:", access_token)

                # 获取用户角色信息（若存在，取第一个）
                user_roles = UserRole.objects.filter(user=user).select_related('role')
                role_key = user_roles[0].role.key if user_roles else None
                role_display = user_roles[0].role.name if user_roles else None

                # 兼容 Django 内置 User 与自定义 SysUser 字段差异
                date_joined = getattr(user, 'create_time', None) or getattr(user, 'date_joined', None)
                user_data = {
                    'id': getattr(user, 'id', None),
                    'username': getattr(user, 'username', ''),
                    'email': getattr(user, 'email', ''),
                    'avatar': getattr(user, 'avatar', None),
                    'phonenumber': getattr(user, 'phonenumber', None),
                    'nickname': getattr(user, 'nickname', None),
                    'gender': getattr(user, 'gender', None),
                    'birthday': getattr(user, 'birthday', None),
                    'bio': getattr(user, 'bio', None),
                    'is_active': getattr(user, 'is_active', False),
                    'date_joined': date_joined,
                    'role_key': role_key,
                    'role_display': role_display,
                }

                return Response({
                    'code': 200,
                    'message': '登录成功',
                    'data': {
                        'token': access_token,
                        'user': user_data
                    }
                })
            else:
                return Response({
                    'code': 400,
                    'message': '密码错误'
                })
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'用户名与密码不正确，登录失败'
            })


class UserInfoView(APIView):
    permission_classes = [IsAuthenticated]  # 只允许认证用户访问

    # 用户信息
    def get(self, request):
        """
        获取用户信息
        :param request:
        :return:
        """
        user = request.user

        try:
            # 获取用户角色信息（若存在，取第一个）
            user_roles = UserRole.objects.filter(user=user).select_related('role')
            role_key = user_roles[0].role.key if user_roles else None
            role_display = user_roles[0].role.name if user_roles else None

            # 兼容 Django 内置 User 与自定义 SysUser 字段差异
            date_joined = getattr(user, 'create_time', None) or getattr(user, 'date_joined', None)
            user_data = {
                'id': getattr(user, 'id', None),
                'username': getattr(user, 'username', ''),
                'email': getattr(user, 'email', ''),
                'avatar': getattr(user, 'avatar', None),
                'phonenumber': getattr(user, 'phonenumber', None),
                'nickname': getattr(user, 'nickname', None),
                'gender': getattr(user, 'gender', None),
                'birthday': getattr(user, 'birthday', None),
                'bio': getattr(user, 'bio', None),
                'is_active': getattr(user, 'is_active', False),
                'date_joined': date_joined,
                'role_key': role_key,
                'role_display': role_display,
            }
            return Response({
                'code': 200,
                'message': '获取用户信息成功',
                'data': user_data
            })
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'获取用户信息失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def put(self, request):
        """
        更新用户信息
        :param request:
        :return:
        """
        user = request.user

        try:
            # 获取请求中的用户信息
            user_data = request.data

            # 只允许更新的字段白名单
            allowed_fields = {
                'email', 'phonenumber', 'nickname', 'gender', 'birthday', 'bio', 'avatar'
            }

            # 规范化并安全更新字段
            for key, value in user_data.items():
                if key not in allowed_fields:
                    continue

                # 生日字段格式处理：允许 'YYYY-MM-DD' 字符串
                if key == 'birthday':
                    if value in (None, ''):
                        setattr(user, 'birthday', None)
                    else:
                        try:
                            # 兼容字符串日期
                            if isinstance(value, str):
                                value_date = datetime.datetime.strptime(value, '%Y-%m-%d').date()
                                setattr(user, 'birthday', value_date)
                            # 兼容 Python 日期对象
                            elif isinstance(value, datetime.date):
                                setattr(user, 'birthday', value)
                            else:
                                raise ValueError('生日格式不正确，应为 YYYY-MM-DD')
                        except Exception as date_err:
                            return Response({
                                'code': 400,
                                'message': f'生日格式错误: {str(date_err)}'
                            }, status=status.HTTP_400_BAD_REQUEST)
                    continue

                # 其他字段直接赋值
                if hasattr(user, key):
                    setattr(user, key, value)

            if hasattr(user, 'save'):
                user.save()

            # 返回更新后的用户信息（兼容两种模型）
            date_joined = getattr(user, 'create_time', None) or getattr(user, 'date_joined', None)
            updated_user_data = {
                'id': getattr(user, 'id', None),
                'username': getattr(user, 'username', ''),
                'email': getattr(user, 'email', ''),
                'avatar': getattr(user, 'avatar', None),
                'phonenumber': getattr(user, 'phonenumber', None),
                'nickname': getattr(user, 'nickname', None),
                'gender': getattr(user, 'gender', None),
                'birthday': getattr(user, 'birthday', None),
                'bio': getattr(user, 'bio', None),
                'is_active': getattr(user, 'is_active', False),
                'date_joined': date_joined
            }

            return Response({
                'code': 200,
                'message': '用户信息更新成功',
                'data': updated_user_data
            })
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'更新用户信息失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class AvatarUploadView(APIView):
    """
    用户头像上传视图类
    支持上传JPG、PNG、GIF格式的图片文件，最大5MB
    """
    permission_classes = [IsAuthenticated]  # 只允许认证用户访问

    def post(self, request):
        """
        上传用户头像
        :param request: 包含头像文件的请求
        :return: 返回上传结果
        """
        user = request.user

        # 检查是否有上传的文件
        if 'avatar' not in request.FILES:
            return Response({
                'code': 400,
                'message': '请选择要上传的头像文件'
            }, status=status.HTTP_400_BAD_REQUEST)

        avatar_file = request.FILES['avatar']

        # 验证文件类型
        allowed_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp']
        file_extension = os.path.splitext(avatar_file.name)[1].lower()

        if file_extension not in allowed_extensions:
            return Response({
                'code': 400,
                'message': '不支持的文件格式，请上传 jpg、jpeg、png、gif 或 bmp 格式的图片'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 验证文件大小（限制为5MB）
        max_size = 5 * 1024 * 1024  # 5MB
        if avatar_file.size > max_size:
            return Response({
                'code': 400,
                'message': '文件大小不能超过5MB'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 创建上传目录
            upload_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'media', 'avatars')
            os.makedirs(upload_dir, exist_ok=True)

            # 生成唯一的文件名
            unique_filename = f"{uuid.uuid4().hex}{file_extension}"
            file_path = os.path.join(upload_dir, unique_filename)

            # 保存文件
            with open(file_path, 'wb+') as destination:
                for chunk in avatar_file.chunks():
                    destination.write(chunk)

            # 生成访问URL
            avatar_url = f"/media/avatars/{unique_filename}"

            # 删除旧头像文件（如果存在）
            if user.avatar and user.avatar != '':
                try:
                    old_avatar_path = user.avatar.replace('/media/', '')
                    old_file_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'media', old_avatar_path)
                    if os.path.exists(old_file_path):
                        os.remove(old_file_path)
                except Exception as e:
                    print(f"删除旧头像失败: {e}")

            # 更新用户头像字段
            user.avatar = avatar_url
            user.save()

            return Response({
                'code': 200,
                'message': '头像上传成功',
                'data': {
                    'avatar': avatar_url
                }
            })

        except Exception as e:
            return Response({
                'code': 500,
                'message': f'头像上传失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class ChangePasswordView(APIView):
    """
    修改密码视图类
    支持用户修改自己的密码，需要验证旧密码
    """
    permission_classes = [IsAuthenticated]  # 只允许认证用户访问

    def post(self, request):
        """
        修改用户密码
        :param request: 包含旧密码和新密码的请求
        :return: 返回修改结果
        """
        user = request.user

        # 获取请求参数
        old_password = request.data.get('old_password')
        new_password = request.data.get('new_password')

        # 验证参数完整性
        if not old_password or not new_password:
            return Response({
                'code': 400,
                'message': '旧密码和新密码不能为空'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 验证新密码长度
        if len(new_password) < 6:
            return Response({
                'code': 400,
                'message': '新密码长度不能少于6位'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 验证旧密码是否正确
            if not check_password(old_password, user.password):
                return Response({
                    'code': 400,
                    'message': '旧密码错误'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 验证新密码不能与旧密码相同
            if old_password == new_password:
                return Response({
                    'code': 400,
                    'message': '新密码不能与旧密码相同'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 使用Django的密码哈希函数对新密码进行加密
            hashed_new_password = make_password(new_password)

            # 更新用户密码
            user.password = hashed_new_password
            user.save()

            return Response({
                'code': 200,
                'message': '密码修改成功'
            })

        except Exception as e:
            return Response({
                'code': 500,
                'message': f'密码修改失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class AdminUserPagination(PageNumberPagination):
    page_size_query_param = 'page_size'


class AdminUserListCreateView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        """
        列表 + 搜索
        支持：username(模糊)、email(模糊)、status(0/1)、role_key(按角色过滤)
        分页：page, page_size
        """
        username = request.query_params.get('username', '')
        email = request.query_params.get('email', '')
        status_q = request.query_params.get('status', '')
        role_key = request.query_params.get('role_key', '')

        queryset = SysUser.objects.all().order_by('-id')
        if username:
            queryset = queryset.filter(username__icontains=username)
        if email:
            queryset = queryset.filter(email__icontains=email)
        if status_q in ['0', '1']:
            queryset = queryset.filter(status=int(status_q))
        if role_key:
            # 通过 UserRole 的 related_name=user_roles 进行反向过滤
            queryset = queryset.filter(user_roles__role__key=role_key)

        paginator = AdminUserPagination()
        page = paginator.paginate_queryset(queryset, request)

        def build_user(u: SysUser):
            # 获取用户角色（简化为取第一个角色名称）
            user_roles = UserRole.objects.filter(user=u).select_related('role')
            role_name = user_roles[0].role.name if user_roles else ''
            role_key = user_roles[0].role.key if user_roles else ''
            return {
                'id': u.id,
                'username': u.username,
                'email': u.email,
                'role_name': role_name,
                'role_key': role_key,
                'is_active': u.is_active,
                'date_joined': getattr(u, 'create_time', None) or getattr(u, 'date_joined', None)
            }

        results = [build_user(u) for u in page]
        return paginator.get_paginated_response({'code': 200, 'message': '获取成功', 'results': results})

    def post(self, request):
        """
        新增用户
        body: username, password, email?, role_key?, is_active?(bool)
        """
        username = request.data.get('username')
        password = request.data.get('password')
        email = request.data.get('email', '')
        role_key = request.data.get('role_key')
        is_active = request.data.get('is_active', True)

        if not username or not password:
            return Response({'code': 400, 'message': '用户名与密码不能为空'}, status=status.HTTP_400_BAD_REQUEST)
        if SysUser.objects.filter(username=username).exists():
            return Response({'code': 400, 'message': '用户名已存在'}, status=status.HTTP_400_BAD_REQUEST)

        user = SysUser.objects.create(
            username=username,
            password=make_password(password),
            email=email,
            status=0 if is_active else 1,
            create_time=datetime.datetime.now(),
            update_time=datetime.datetime.now(),
            nickname=username,
            gender='other',
        )

        # 绑定角色
        if role_key:
            try:
                role = Role.objects.get(key=role_key)
                UserRole.objects.create(user=user, role=role)
            except Role.DoesNotExist:
                pass

        return Response({'code': 200, 'message': '创建成功', 'data': {'id': user.id}})


class AdminUserDetailView(APIView):
    permission_classes = [IsAuthenticated]

    def put(self, request, user_id: int):
        """
        编辑用户（用户名不允许修改）
        body: email?, role_key?, is_active?
        """
        try:
            user = SysUser.objects.get(id=user_id)
        except SysUser.DoesNotExist:
            return Response({'code': 404, 'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)

        email = request.data.get('email')
        role_key = request.data.get('role_key')
        is_active = request.data.get('is_active')

        if email is not None:
            user.email = email
        if is_active is not None:
            user.status = 0 if bool(is_active) else 1

        user.save()

        # 更新角色：先清空，再绑定新角色
        if role_key is not None:
            UserRole.objects.filter(user=user).delete()
            if role_key:
                try:
                    role = Role.objects.get(key=role_key)
                    UserRole.objects.create(user=user, role=role)
                except Role.DoesNotExist:
                    pass

        return Response({'code': 200, 'message': '更新成功'})

    def delete(self, request, user_id: int):
        try:
            user = SysUser.objects.get(id=user_id)
        except SysUser.DoesNotExist:
            return Response({'code': 404, 'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)
        user.delete()
        return Response({'code': 200, 'message': '删除成功'})


class AdminUserToggleStatusView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request, user_id: int):
        try:
            user = SysUser.objects.get(id=user_id)
        except SysUser.DoesNotExist:
            return Response({'code': 404, 'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)
        user.status = 1 if user.status == 0 else 0
        user.save()
        return Response({'code': 200, 'message': '状态已更新', 'data': {'is_active': user.is_active}})


class AdminUserResetPasswordView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request, user_id: int):
        try:
            user = SysUser.objects.get(id=user_id)
        except SysUser.DoesNotExist:
            return Response({'code': 404, 'message': '用户不存在'}, status=status.HTTP_404_NOT_FOUND)

        user.password = make_password('123456')
        user.save()
        return Response({'code': 200, 'message': '密码已重置为 123456'})


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def search_users(request):
    """搜索用户"""
    try:
        username = request.GET.get('username', '')

        if not username:
            return Response({
                'success': False,
                'error': '用户名不能为空'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 搜索用户名包含指定字符串的用户
        users = SysUser.objects.filter(username__icontains=username)

        # 格式化用户数据
        user_list = []
        for user in users:
            user_list.append({
                'id': user.id,
                'username': user.username,
                'email': user.email,
                'phonenumber': user.phonenumber,
            })

        return Response({
            'success': True,
            'users': user_list
        })
    except Exception as e:
        return Response({
            'success': False,
            'error': f'搜索用户失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)